from __future__ import unicode_literals
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView

from oauth.models import OAuthQQUser
from oauth.serializers import OAuthQQUserSerializer
from oauth.utils import generic_openid_token

"""
实现第三方登陆的步骤：
第一步： 先到相应的开发平台中，申请成为开发者
            个人开发者
            企业开发者
第二步： 成为开发者之后，申请应用
            appid
            appsecret
第三步： 按照文档开发就可以

    1.添加图标
    2.添加图标的按钮点击
    3.点击图标的时候调转到一个页面
    4.这个页面需要用户同意，同意之后获取一个code
    5.通过code换取token
    6.通过token 换取 openid

        openid是此网站上唯一对应用户身份的标识，
        网站可将此ID进行存储便于用户下次登录时辨识其身份，
        或将其与用户在网站上的原有账号进行绑定。
        openid 要和 已有账号进行一个 1:1的关系

        openid      user
        abc         1


                                第三方网站 保存这个就可以
    QQ  12345678        -->      abcdefg

    OAuth2.0
    对于应用而言，需要进行两步：
        1. 获取Authorization Code；
        2. 通过Authorization Code获取Access Token

"""


"""
我们后端 需要拼接 跳转的url，拼接成功之后，返回给前端

看接口文档
"""
from QQLoginTool.QQtool import OAuthQQ
from meiduo_mall import settings

class OauthQQUrlAPIView(APIView):
    # /oauth/qq/statues/
    def get(self,request):

        # auth_url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=101474184&redirect_uri=http://www.meiduo.site:8080/oauth_callback.html&state=test'
        state = 'test'
        state = '/'
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=state)

        auth_url = qq.get_qq_url()

        return Response({'auth_url':auth_url})



"""
当用户同意登陆之后， 腾讯的服务器会生成一个code， 这个code在回调的url中
我们需要让前端将 code 传递给后端

我们后端需要 通过code 换取token

一，大体的步骤
    1. 接收code
    2. 通过code换取token （是我们通过 请求 向腾讯的服务器换）
    3. 通过token换取openid (openid是此网站上唯一对应用户身份的标识)
二，确定请求方式和路由
    GET      /oauth/qq/users/?code=xxx
三，确定使用哪个视图


"""

class OAuthQQUserAPIView(APIView):

    def get(self,request):
        # 1. 接收code
        code = request.query_params.get('code')
        if code is None:
            from rest_framework import status

            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 2. 通过code换取token （是我们通过 请求 向腾讯的服务器换）

        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI)
        token = qq.get_access_token(code)

        #'9C980C27C0B341C669776DFF747D74B0'

        #3A883CA9CB6CDFEA30906452E468748F


        #'0E98A943DE5E09615511B17D5EF8C1C6'
        # 3. 通过token换取openid (openid是此网站上唯一对应用户身份的标识)
        openid = qq.get_open_id(token)

        #4. 我们需要根据openid进行判断 （根据openid进行查询）
        # 如果用户绑定过，则直接登陆
        # 如果用户没有绑定过，则进行绑定
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 说明不存在， 就应该绑定
            return Response({'access_token':openid})
        else:
            # 说明存在， 存在应该登陆
            # 返回 token，username,userid

            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(qquser.user)
            token = jwt_encode_handler(payload)

            return Response({
                'user_id':qquser.user.id,
                'username':qquser.user.username,
                'token':token
            })

        pass

    def post(self, request):
        # 1.接收参数 mobile,password,sms_code,access_token
        data = request.data
        # 2.验证数据
        #     access_token
        #     sms_code
        #     根据手机号判断用户是否注册过
        serializer = OAuthQQUserSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        # 3.保存数据
        qquser = serializer.save()
        # 4.返回相应(登陆)
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(qquser.user)
        token = jwt_encode_handler(payload)

        return Response({
            'user_id': qquser.user.id,
            'username': qquser.user.username,
            'token': token
        })

    """
    当用户点击头像授权同意的时候，后端会将 生成的code换取成最终的openid，然后返回给前端

    当用户点击保存按照的时候，需要让前端将 手机号，密码，短信验证码以及 加密之后的openid提交给后端

    后端：
        大体思路：
        1.接收参数 mobile,password,sms_code,access_token
        2.验证数据
            access_token
            sms_code
            根据手机号判断用户是否注册过

        3.保存数据
        4.返回相应

        请求方式和路由
            POST

    """

###########################JWS###############################
from itsdangerous import JSONWebSignatureSerializer # 没有时间
# 我们不用上边的那个


# 1.导入
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from meiduo_mall import settings
#2. 初始化，创建序列化器实例对象
# secret_key, expires_in=None
# secret_key        密钥 一般（习惯）使用 setting 中的 secret_key
# expires_in=None   过期时间，单位是秒数
serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)

#3. 组织数据
data = {
    'openid':'123'
}

#4. 对数据进行加密（签名）
token = serializer.dumps(data)

token.decode()


##########################验证数据##################################

#1.创建序列化器
serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)

#2. 对数据进行解密（验证）
serializer.loads(token)


##########################验证数据的合法性##################################
# 被篡改 时效


serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=1000)

data = {'openid':'123'}

token = serializer.dumps(data)


serializer.loads(token)